package yxy.game.pm2.module.coin;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormat;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.levydate;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.ArrayList;
import java.util.Map;

/** 兑换金币模块 */
public class CoinModule extends PlayerModule {
	// bean===========================================================================

	private ArrayList<CoinBean> coinBeans = new ArrayList<>();// 购买次数
	private DateTime time;

	public ArrayList<CoinBean> getCoinBeans() {
		return coinBeans;
	}

	public void setCoinBeans(ArrayList<CoinBean> coinBeans) {
		this.coinBeans = coinBeans;
	}

	public DateTime getTime() {
		return time;
	}

	public void setTime(DateTime time) {
		this.time = time;
	}

	// func===========================================================================

	public void update() {
		DateTime now = DateTime.now();
		if (getTime() == null || !new LocalDate(now).equals(new LocalDate(getTime()))) {
			_update(now);
			return;
		}
		if (checkTimeZone(now) != checkTimeZone(getTime())) {
			_update(now);
		}
	}

	private void _update(DateTime now) {
		try {
			if (tryLock()) {
				setTime(now);
				for (CoinBean coin : getCoinBeans()) {
					coin.setTimes(0);
				}
				set();

				checkTimes();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			unlock();
		}
	}

	private int checkTimeZone(DateTime time) {
		DateTime[] zone = new DateTime[3];
		for (int i = zone.length - 1; i >= 0; i--) {
			zone[i] = zoneTime(i);
		}
		for (int i = zone.length - 1; i >= 0; i--) {
			if (!time.isBefore(zone[i])) {
				return i;
			}
		}
		return 0;
	}

	public long refreshTime() {
		DateTime now = DateTime.now();
		return zoneTime(checkTimeZone(now) + 1).getMillis() - now.getMillis();
	}

	static public DateTime zoneTime(int zone) {
		switch (zone) {
		case 1:
			return new LocalDate().toDateTime(LocalTime.parse("09:00", DateTimeFormat.forPattern("HH:mm")));
		case 2:
			return new LocalDate().toDateTime(LocalTime.parse("19:00", DateTimeFormat.forPattern("HH:mm")));
		case 3:
			return new LocalDate().plusDays(1).toDateTimeAtStartOfDay();
		default:
			return new LocalDate().toDateTimeAtStartOfDay();
		}
	}

	public void checkTimes() {
		for (CoinBean coinBean : getCoinBeans()) {
			Currency cost = coinBean.cost();
			if (coinBean.times() > 0 && (cost == null || cost.getNumber() <= 0)) {
				new TipHandle().updateTip(getPlayerCode(), TipType.钱币_按钮, true);
				return;
			}
		}
		new TipHandle().updateTip(getPlayerCode(), TipType.钱币_按钮, false);
	}

	// redis==========================================================================

	private static String key(String playerCode) {
		return String.format("PLAYER:%s:MODULE:COIN", playerCode);
	}

	public void set() {
		try {
			setv(key(getPlayerCode()), this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	static public CoinModule get(String playerCode) {
		try {
			CoinModule module = getv(key(playerCode));
			if (module == null) {
				module = MySQLCacheDAO.getV(key(playerCode), CoinModule.class);
				if(module != null){module.set();}//把数据同步到redis
			}

			if (module == null) {
				module = create(playerCode);
			}
			module.update();
			return module;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	static public CoinModule create(String playerCode) {
		Map<String, levydate> datas = DataCenter.getAllData(levydate.class);
		CoinModule module = new CoinModule();
		module.setPlayerCode(playerCode);

		for (levydate data : datas.values()) {
			CoinBean coinBean = new CoinBean();
			coinBean.setDataId(data.getId());
			module.getCoinBeans().add(coinBean);
		}
		module.setTime(DateTime.now());
		module.set();
		return module;
	}

	//存储到数据库的方法
	public static void saveToDB(String playerCode) {
		try {
			String key = key(playerCode);

			if (touchBucket(key(playerCode)).isExists()) {
				CoinModule module = getv(key(playerCode));
				MySQLCacheDAO.setV(key, module);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//从redis移走数据的操作
	public static void removeAllFromRedis(String playerCode) {
		try {
			touchBucket(key(playerCode)).delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// lock==========================================================================

	public String lockKey() {
		return String.format("lock:%s", key(getPlayerCode()));
	}

	static public RedisLock lock(String playerCode) {
		return getLock(String.format("lock:%s", key(playerCode)));
	}
}
